package com.fxm.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollectionUtil;
import com.fxm.client.UserClient;
import com.fxm.constant.RedisConstants;
import com.fxm.domain.User;
import com.fxm.enums.SessionEnum;
import com.fxm.returns.RespCode;
import com.fxm.returns.RespEntity;
import com.fxm.returns.RespTable;
import com.fxm.utils.RedisUtil;
import com.fxm.vo.param.LoginParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.*;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * <p>
 * 用户管理 前端控制器
 * </p>
 *
 * @author fxm
 * @since 2021-02-03
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Api(value = "用户管理", tags = "用户管理")
public class UserController {

    @Autowired
    private UserClient userClient;

    @Autowired
    private RedisUtil redisUtil;

    @PostMapping("/loginUser")
    @ApiOperation(value = "管理员登陆")
    public RespEntity loginUser(String username, String password, String mobile, String code, HttpSession session){
        String oldCode = redisUtil.hget(RedisConstants.key.SMS, mobile);
        if (! StringUtils.equals(code, oldCode)) {
            return new RespEntity(RespCode.CODE_ERROR);
        }
        RespEntity<User> respEntity = userClient.login(new LoginParam(username, password));
        if (Objects.isNull(respEntity.getData())) {
            return new RespEntity(RespCode.LOGIN_ERROR);
        }
        session.setAttribute(SessionEnum.USER.getCode(), respEntity.getData());
        return new RespEntity(RespCode.SUCCESS);
    }

    @PostMapping("/welcome")
    @ApiOperation(value = "首页欢迎语和头像展示")
    public RespEntity<User> welcome(HttpSession session) {
        User user = (User) session.getAttribute(SessionEnum.USER.getCode());
        return new RespEntity(RespCode.SUCCESS, user);
    }

    @PostMapping("/exitUser")
    @ApiOperation(value = "退出登陆功能")
    public RespEntity exitUser(HttpSession session) {
        session.removeAttribute(SessionEnum.USER.getCode());
        redisUtil.del(RedisConstants.key.SMS);
        return new RespEntity(RespCode.SUCCESS);
    }

    @GetMapping("/list")
    @ApiOperation(value = "用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "page", value = "当前页数", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "limit", value = "每页数量", required = true)
    })
    public RespTable<List<User>> queryAllUser(@RequestParam(value = "page", required = true) Integer page,
                                              @RequestParam(value = "limit", required = true) Integer limit) {
        RespTable<List<User>> respTable = userClient.queryAllUser(page, limit);
        return respTable;
    }

    @GetMapping("/search")
    @ApiOperation(value = "搜索用户")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "page", value = "当前页数", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "limit", value = "每页数量", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "column", value = "字段名", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "limit", value = "字段值", required = true)
    })
    public RespTable<List<User>> searchUser(@RequestParam(value = "page", required = true) Integer page,
                                            @RequestParam(value = "limit", required = true) Integer limit,
                                            @RequestParam(value = "column", required = true) String column,
                                            @RequestParam(value = "value", required = true) String value) {
        RespTable<List<User>> respTable = userClient.searchUser(page, limit, column, value);
        return respTable;
    }

    @GetMapping("/chinaMap")
    @ApiOperation(value = "登陆用户地区分布-中国地图")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "beginDate", value = "开始时间", required = false),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "endDate", value = "结束时间", required = false)
    })
    public RespEntity chinaMap(@RequestParam(value = "beginDate", required = false) String beginDate,
                               @RequestParam(value = "endDate", required = false) String endDate) {
        RespEntity respEntity = userClient.chinaMap(beginDate, endDate);
        return respEntity;
    }

    @GetMapping("/provinceMap")
    @ApiOperation(value = "登陆用户地区分布-省份地图")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "province", value = "省份名称", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "beginDate", value = "开始时间", required = false),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "endDate", value = "结束时间", required = false)
    })
    public RespEntity provinceMap(@RequestParam(value = "province", required = true) String province,
                                  @RequestParam(value = "beginDate", required = false) String beginDate,
                                  @RequestParam(value = "endDate", required = false) String endDate) {
        RespEntity respEntity = userClient.provinceMap(province, beginDate, endDate);
        return respEntity;
    }

    @GetMapping("/send")
    @ApiOperation(value = "发送短信验证码")
    @ApiImplicitParam(paramType = "query", dataType = "String", name = "mobile", value = "手机号", required = true)
    public RespEntity<Integer> sendMsg(@RequestParam(value = "mobile", required = true) String mobile) {
        RespEntity<Integer> respEntity = userClient.sendSms(mobile);
        return respEntity;
    }

    @GetMapping("/exportExcel")
    @ApiOperation(value = "批量导出Excel")
    public void exportExcel(Integer[] ids, HttpServletResponse response) throws Exception {
        RespEntity<List<User>> respEntity = userClient.queryUserByIds(ids);
        List<User> userList  = (List<User>) respEntity.getData();
        if (CollectionUtil.isNotEmpty(userList)) {
            for (User user : userList) {
                if (StringUtils.isBlank(user.getCountry())) {
                    user.setCountry("null");
                }
                if (StringUtils.isBlank(user.getProvince())) {
                    user.setProvince("null");
                }
                if (StringUtils.isBlank(user.getCity())) {
                    user.setCity("null");
                }
            }
        }
        ExportParams exportParams = new ExportParams("用户数据信息", "用户");
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList);
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-disposition","attachment;filename=user_"+new Date().getTime()+".xls");
        workbook.write(response.getOutputStream());
    }

    @GetMapping("/exportExcelAll")
    @ApiOperation(value = "全部导出Excel")
    public void exportExcelAll(HttpServletResponse response) throws IOException {
        RespEntity<List<User>> respEntity = userClient.allUser();
        List<User> userList = (List<User>) respEntity.getData();
        if (CollectionUtil.isNotEmpty(userList)) {
            for (User user : userList) {
                if (StringUtils.isBlank(user.getCountry())) {
                    user.setCountry("null");
                }
                if (StringUtils.isBlank(user.getProvince())) {
                    user.setProvince("null");
                }
                if (StringUtils.isBlank(user.getCity())) {
                    user.setCity("null");
                }
            }
        }
        ExportParams exportParams = new ExportParams("用户数据信息", "sheet1");
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList);
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-disposition","attachment;filename=user_"+new Date().getTime()+".xls");
        workbook.write(response.getOutputStream());
    }

    @PostMapping("/ban")
    @ApiOperation(value = "封禁用户")
    @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "id", value = "用户id", required = true)
    public RespEntity banUser(@RequestParam(value = "id", required = true) Integer id) {
        RespEntity respEntity = userClient.banUser(id);
        return respEntity;
    }

    @GetMapping("/sex")
    @ApiOperation(value = "用户性别统计")
    public RespEntity sexCount() {
        RespEntity respEntity = userClient.sexCount();
        return respEntity;
    }

    @GetMapping("/blacklist")
    @ApiOperation(value = "用户黑名单列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "page", value = "当前页数", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "limit", value = "每页数量", required = true)
    })
    public RespTable<List<User>> blackList(@RequestParam(value = "page", required = true) Integer page,
                                           @RequestParam(value = "limit", required = true) Integer limit) {
        RespTable<List<User>> respTable = userClient.blackList(page, limit);
        return respTable;
    }

    @PostMapping("/unseal")
    @ApiOperation(value = "用户解封")
    @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "id", value = "用户id", required = true)
    public RespEntity unseal(@RequestParam("id") Integer id) {
        RespEntity respEntity = userClient.unseal(id);
        return respEntity;
    }

}
